#include <iostream>
#include <windows.h>
#define BUFFER_SIZE 10

int buffer[BUFFER_SIZE];
DWORD WINAPI ConsumerProc(LPVOID lpParameter);
DWORD WINAPI ProducerProc(LPVOID lpParameter);
HANDLE ghMutex;
int index = -1;

int main()
{
    HANDLE hThreadProducer;
    HANDLE hThreadConsumer;

    // 初始化互斥锁
    ghMutex = CreateMutex(NULL, FALSE, NULL);

    // 创建生产者与消费者线程
    hThreadConsumer = CreateThread(NULL, 0, ConsumerProc, NULL, 0, NULL);
    Sleep(1);
    hThreadProducer = CreateThread(NULL, 0, ProducerProc, NULL, 0, NULL);

    // 终止前等待线程结束
    WaitForSingleObject(hThreadConsumer, INFINITE);
    WaitForSingleObject(hThreadProducer, INFINITE);

    // 释放互斥锁及其他相关句柄
    CloseHandle(ghMutex);
    CloseHandle(hThreadConsumer);
    CloseHandle(hThreadProducer);

    return 0;
}

// 生产者线程
DWORD WINAPI ProducerProc(LPVOID lpParameter)
{
    int value;
    while (true)
    {
        Sleep(1000);  // 生产者睡眠 100ms

        // 检查缓冲区是否已满,如果已满则休息
        if (index == BUFFER_SIZE - 1) {
            continue;
        }

        // 准备要生成的数据
        value = (rand() % 128) + 1;
        std::cout << "Producer: index: " << index + 1 << ", generate value: " << value << std::endl;
   
        // 抢占缓冲区并将生产的数据放入缓冲区
        WaitForSingleObject(ghMutex, INFINITE);
        buffer[++index] = value;
        ReleaseMutex(ghMutex);
    }
    return 0;
}

// 消费者线程
DWORD WINAPI ConsumerProc(LPVOID lpParameter)
{
    while (true)
    {
        Sleep(2000);
        // 如果没有已生产的数据则再等会
        if (index == -1) {
            continue;
        }

        char data;
        int i;
        // 抢占缓冲区并读取缓冲区中已生产的数据
        WaitForSingleObject(ghMutex, INFINITE);
        i = index;
        data = buffer[index--];
        ReleaseMutex(ghMutex);

        std::cout << "Consumer: index: " << i << ", value: " << data << std::endl;
 
    }
    return 0;
}